#ifndef __DELEGATE_H__
#define __DELEGATE_H__

class  DUI_API CDelegateBase
{
public:
    CDelegateBase(void* pObject, void* pFn);
    CDelegateBase(const CDelegateBase& rhs);
    virtual ~CDelegateBase();
    bool Equals(const CDelegateBase& rhs) const;
    bool operator() (TEventUI& event);
    virtual CDelegateBase* Copy();

    void* GetFn();
    void* GetObject();
	virtual bool Invoke(TEventUI& event)
	{
		return false;
	}
private:
    void* m_pObject;
    void* m_pFn;
};


template <class T>
class CDelegate : public CDelegateBase
{
    typedef bool (T::* Fn)(TEventUI&);
public:
    CDelegate(T* pObj, Fn pFn) : CDelegateBase(pObj, &pFn), m_pFn(pFn) { }
    CDelegate(const CDelegate& rhs) : CDelegateBase(rhs) { m_pFn = rhs.m_pFn; } 
protected:
    virtual bool Invoke(TEventUI& event)
    {
       T* pObject = (T*) GetObject();
        return (pObject->*m_pFn)(event); 
	}  
	virtual CDelegateBase* Copy()
	{
		return new CDelegate(*this);
	}
private:
    Fn m_pFn;
};

template <class T>
CDelegate<T>  MakeDelegate(T* pObject, bool (T::* pFn)(TEventUI&))
{
	return CDelegate<T>(pObject, pFn);
}


class  DUI_API CEventDelegate
{
	typedef bool (*FnType)(TEventUI&);
public:
	CEventDelegate();
	~CEventDelegate();
	int GetCount();
	void operator+= (CDelegateBase& d);
	void operator-= (CDelegateBase& d);
	bool Invoke(TEventUI& event);
	void Clear();

protected:
	CStdPtrArray m_aDelegates;
};

#endif // __DELEGATE_H__